package platformmanager

import (
	"context"
	"errors"
	"fmt"
	"github.com/robfig/cron/v3"
	"iot-base/auth/api/logic/platformmanager/airdata"
	"iot-base/auth/api/logic/platformmanager/platformconn"
	"iot-base/auth/logger"
	"iot-base/auth/model"
	"iot-base/auth/svc"
)

var PlatformMap = make(map[int64]task)
var ReportTimeFlag cron.EntryID

type task struct {
	Protocol Protocol
	Param    map[string]interface{}
}

type CronStatus struct {
	Cancel context.CancelFunc
}

func UpdatePlatform(v model.Platform) error {
	t := GetTaskFromMap(v.ID)
	fmt.Println(t)
	platformconn.DelPlatformConnById(v.ID)
	delete(PlatformMap, v.ID)
	if !v.Status {
		return nil
	}
	addr := v.IP + ":" + v.Port
	platformC := platformconn.PlatformConn{
		IP:   addr,
		Send: make(chan []byte),
		Rev:  make(chan platformconn.PlatformRev),
		Stop: make(chan struct{}),
	}
	p, ok := ProtocolMap[v.ProtocolName]
	if !ok {
		return errors.New("no this protocol")
	}
	if v.Real {
		p.RegisterData(v.ID, "real", "air")
	} else {
		p.UnRegisterData(v.ID, "real", "air")
	}
	if v.Minute5 {
		p.RegisterData(v.ID, "5minute", "air")
	} else {
		p.UnRegisterData(v.ID, "5minute", "air")
	}
	if v.Hour {
		p.RegisterData(v.ID, "hour", "air")
	} else {
		p.UnRegisterData(v.ID, "hour", "air")
	}
	if v.Dev {
		p.RegisterData(v.ID, "5minute", "dev")
		p.RegisterData(v.ID, "hour", "dev")
	} else {
		p.UnRegisterData(v.ID, "5minute", "dev")
		p.UnRegisterData(v.ID, "hour", "dev")
	}
	if v.AutoReport {
		ReportTimeFlag, _ = airdata.Cron.AddFunc(fmt.Sprintf("0 0/%v * * * *", v.ReportTime), func() {})
	} else {
		if ReportTimeFlag != 0 {
			airdata.Cron.Remove(ReportTimeFlag)
		}
	}
	//将配置成完成的任务存入map
	platformconn.SetPlatformConnById(v.ID, platformC)
	platformC.Start()
	return nil
}

func DelPlatform(ID int64) {
	delete(PlatformMap, ID)
}

func InitPlatform() {
	platforms, err := svc.Dao.TPlatform.FindAll()
	if err != nil {
		logger.Log.Error(err)
	}
	for _, v := range platforms {
		err := UpdatePlatform(v)
		if err != nil {
			logger.Log.Errorf(err.Error())
		}
	}
}

func GetTaskFromMap(id int64) *task {
	if task, ok := PlatformMap[id]; !ok {
		return nil
	} else {
		return &task
	}
}
